// Create variables for the target and off-target tables.
var rTable = null;
var oTable = null;

// This empty table is displayed as the off-target table, until a candidate target is selected, to prevent an error.
var emptyTable = [];

// This is used for 'aoColumns' parameter when initializing the off-target table.
var offTargetColumns = [
  {"sTitle":"Sequence","bSortable":false,"sClass":"sequence","sToolTip":"Nucleotide sequence of the potential off-target, green for matches to the candidate target, red for mismatches"},
  {"sTitle":"Hamming Distance","sToolTip":"Hamming distance of the potential off-target"},
  {"sTitle":"Strand","sToolTip":"Reference strand off-target is present in, + for forward strand, - for reverse strand"},
  {"sTitle":"Chromosome","sToolTip":"The name of reference strand (usually the chromosome number), the off-target is present in"},
  {"sTitle":"Offset","sToolTip":"0-based offset of the left-most character in the potential off-target, into the reference strand."},
  {"sTitle":"GC","sToolTip":"GC nucleotide percentage of potential off-target"},
  {"sTitle":"Browser","sToolTip":"Link to UCSC genome browser"}
];



/* fnReloadAjax from http://datatables.net/plug-ins/api
Loads a table object from the specified JSON file, then refreshes the off-target table */ 
$.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw ) {
  if ( sNewSource !== undefined && sNewSource !== null ) {
    oSettings.sAjaxSource = sNewSource;
  }
  this.oApi._fnProcessingDisplay( oSettings, true );
  var that = this;
  var iStart = oSettings._iDisplayStart;
  var aData = [];
  this.oApi._fnServerParams( oSettings, aData );
  oSettings.fnServerData.call( oSettings.oInstance, oSettings.sAjaxSource, aData, function(json) {
    /* Clear the old information from the table */
    that.oApi._fnClearTable( oSettings );
    /* Got the data - add it to the table */
    var aData =  (oSettings.sAjaxDataProp !== "") ?
    that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json;
    for ( var i=0 ; i<aData.length ; i++ ) {
      that.oApi._fnAddData( oSettings, aData[i] );
    }
    oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
    that.fnDraw();
    if ( bStandingRedraw === true ) {
      oSettings._iDisplayStart = iStart;
      that.oApi._fnCalculateEnd( oSettings );
      that.fnDraw( false );
    }
    that.oApi._fnProcessingDisplay( oSettings, false );
    /* Callback user function - for event handlers etc */
    if ( typeof fnCallback == 'function' && fnCallback !== null ) {
      fnCallback( oSettings );
    }
  }, oSettings );
};



/* fnProcessingIndicator from http://datatables.net/plug-ins/api
Simple plug-in to display 'Processing', in the table header, when called */
jQuery.fn.dataTableExt.oApi.fnProcessingIndicator = function ( oSettings, onoff ) {
  if( typeof(onoff) == 'undefined' ) {
    onoff=true;
  }
  this.oApi._fnProcessingDisplay( oSettings, onoff );
};



/* Maps the table header of visible columns back to the aaData/aoColumns index
This allows sToolTip from offTargetColumns to be displayed in a tooltip, on hover.
From Fabian's triplex inspector */
$.fn.dataTableExt.oApi.fnGetTh  = function ( oSettings, iTh ) {
  var counter = -1
  var visIndex = 0
  for (visIndex=0;visIndex<oSettings.aoColumns.length;++visIndex) {
    if (oSettings.aoColumns[visIndex]["bVisible"]) {
      ++counter;
    } 
    if (counter == iTh) {
      break;
    } 
  }
  return visIndex;
}



/* Highlights the selected row in the target table and loads the appropriate off-target data
into the off-target table. 
Modified version of Fabian's function */
function selectTarget(){
  $('#candidate-target-table tbody tr').live('click', function () {
    var targetId = $($('td', this)[0]).text();
	
    /* var online is undefined when crispr-search executed from shell */
    if(typeof(online) == 'undefined' ) {
      oTable.fnProcessingIndicator();
      oTable.fnClearTable();
      oTable.fnAddData(offTargetData[targetId]);
      oTable.fnProcessingIndicator(false);
    }
    else {
      oTable.fnReloadAjax( 'json/'+ targetId +'.json' );
    };
  } );
  
  /* Highlight selected row */
  $("#candidate-target-table tbody").click(function(event) {
    $(rTable.fnSettings().aoData).each(function () {
      $(this.nTr).removeClass('row_selected');
    } );
    $(event.target.parentNode).addClass('row_selected');
  } );
}



/* Initializes the off-target table on page load. */
function loadOffTargets() {
  oTable = $('#off-target-table').dataTable( {
    "sDom": '<"H"<"title-ot">frl>t<"F"ip>',
    "bProcessing": true,
    "bAutoWidth":false,
    "bJQueryUI": true,
    "sPaginationType": "full_numbers",
    "aoColumns": offTargetColumns,
    "aaSorting":[[1,"asc"]],
    "aaData": emptyTable
  } );
  
  $(".title-ot").html('Potential Off-targets');
    
  /* add tooltips to off-target table header */	   
  $('#off-target-table thead tr th').each( function(i) {
    this.setAttribute( 'title',  offTargetColumns[rTable.fnGetTh(i)]["sToolTip"]   );
  } );
  $('#off-target-table thead tr th[title]').tooltip( {
    offset: [10, 0],predelay:200,effect:'slide'
  } );  

  selectTarget();
 
}




/* On page ready function.
Creates the tables and allows selecting.. */
$(document).ready(function() {

  /* Sets the variable 'sort' which is used in table initialization to sort the 
  table by the columns containing Hamming distance.
  The number of Hamming columns depends on user specified CRISPR-search
  parameters, so the if statements accounts for each possible number of columns. */
  if (candidateTargetColumns.length == 5) {
    var sort = [[3,"asc"]]
	
  } else if (candidateTargetColumns.length == 6) {
    var sort = [[3,"asc"],[4,"asc"]]
	
  } else if (candidateTargetColumns.length == 7) {
    var sort = [[3,"asc"],[4,"asc"],[5,"asc"]]
	
  } else {
    var sort = [[3,"asc"],[4,"asc"],[5,"asc"],[6,"asc"]]
	
  }
  
  // Initializes the target table, in the place-holder, in the HTML document.
  rTable = $('#candidate-target-table').dataTable( {
    "sDom": '<"H"<"title-ct">frl>t<"F"ip>',
    "bProcessing": false,
    "bJQueryUI": true,
    "sPaginationType": "full_numbers",
    "bAutoWidth":false,
    "aaSorting":sort,
    "aLengthMenu":[[5,10,25,-1],[5,10,25,"All"]],
    "aoColumns": candidateTargetColumns,
    "aaData": candidateTargetData
  } );
  
  // Integrates the title into the table header.
  $(".title-ct").html('Candidate Targets')
  
  // Allows tooltips to the target table header.		   
  $('#candidate-target-table thead tr th').each( function(i) {
    this.setAttribute( 'title',  candidateTargetColumns[rTable.fnGetTh(i)]["sToolTip"]   );
  } );
  $('#candidate-target-table thead tr th[title]').tooltip( {
    offset: [10, 0],predelay:200,effect:'slide',position: 'bottom center'
  } );  

  loadOffTargets();
  
} );
